home *** CD-ROM | disk | FTP | other *** search
- name trim
- page 55,132
- title 'TRIM - excerpt lines of a file'
- ;
- ; TRIM --- excerpts selected columns from each line
- ; of a file and writes them to the selected
- ; output device or file.
- ;
- ; A "filter" for MS-DOS or PC-DOS version 2 or higher,
- ; after the fashion of Unix. Reads from the standard input
- ; (redirectable) and writes to the standard output (redirectable).
- ; Error messages are directed to the standard error device.
- ;
- ; TRIM can be (and usually would be) used in a pipe, e.g.
- ;
- ; | TRIM 7,45 |
- ;
- ; transmits only the characters in columns 7 to 45 (inclusive)
- ; of each line. A minus sign reverses the action, e.g.
- ;
- ; | TRIM -7,45 |
- ;
- ; transmits all characters except those in columns 7 to 45.
- ;
- ; Special actions:
- ;
- ; | TRIM 0 | deletes trailing spaces from lines, and
- ; | TRIM -0 | also discards empty lines
- ;
- ; By A. K. Head, 6 Duffryn Place, Melbourne, Australia 3142
- ; and Ray Duncan, Laboratory Microsystems Inc.
- ;
-
- command equ 80h ; buffer for command tail
- fcb1 equ 5ch ; default file control block #1
- fcb2 equ 6ch ; default file control block #2
-
- buflen equ 16384 ; buffer length, alter to taste
-
- cr equ 0dh ; ASCII carriage return
- lf equ 0ah ; ASCII line feed
- ff equ 0ch ; ASCII form feed
- eof equ 01ah ; End-of-file marker
- tab equ 09h ; ASCII tab code
- blank equ 20h ; ASCII blank
-
- ; DOS 2.x pre-defined handles
- stdin equ 0000 ; standard input file
- stdout equ 0001 ; standard output file
- stderr equ 0002 ; standard error file
- stdaux equ 0003 ; standard auxilliary file
- stdprn equ 0004 ; standard printer file
-
-
- cseg segment para public 'CODE'
-
- assume cs:cseg,ds:cseg
-
- org 100H ; start .COM at 100H
-
- start: jmp near ptr trim
-
- param1 dw 0 ; command parameter #1
- param2 dw 0 ; command parameter #2
- sign dw 0 ; nonzero if "-" in command
- count dw 0 ; column count, current line
- topin dw 0 ; chars in input buffer - 1
- char db 0 ; current character
-
- trim proc far
-
- xor si,si ; initialize buffer pointers
- xor di,di
- mov bx,fcb1+1 ; addr of parsed parameter 1
- call getprm ; convert it
- cmp ax,0
- je trunc ; zero parameter, go truncate
- ; trailing blanks etc.
- mov param1,ax ; save first parameter
- mov bx,fcb2+1 ; addr of parsed parameter 2
- cmp byte ptr [bx],blank ; is it present at all?
- jne trim0 ; yes, proceed
- jmp err3 ; no, exit
- trim0:
- call getprm ; convert it
- mov param2,ax ; save 2nd parameter
- cmp ax,param1 ; is end column < start column?
- jnb trim1
- jmp err3 ; yes, exit with error message
-
- trim1: mov count,0 ; starting a new line,
- ; initialize column counter
-
- trim2: inc count ; count characters
- call cin ; read a character
- mov al,char ; is it carriage return?
- and al,07fh ; (ignore high bit in case
- cmp al,cr ; this is Wordstar file)
- je trim5 ; yes, found end of line
- mov ax,count ; fetch current char count
- cmp sign,0 ; is this include or exclude call?
- jne trim4 ; jump, -, exclude range
- ; proceed, +, include range
- cmp ax,param1 ; is column counter within
- ; desired range?
- jb trim2 ; no, discard this char.
- cmp ax,param2
- ja trim2 ; no, discard this char.
-
- trim3: call cout ; yes, use this character
- jmp trim2 ; get next char.
-
- trim4: cmp ax,param1 ; is column counter outside
- ; of excluded range?
- jb trim3 ; yes, use this character
- cmp ax,param2
- ja trim3 ; yes, use this character
- jmp trim2 ; no, discard this character
-
- trim5: ; found end of line
- call cout ; write carriage return
- call cin ; read presumed line feed
- call cout ; write line feed
- jmp trim1
-
-
- trunc: ; come here if zero parameter
- ; to delete trailing blanks from
- ; all lines. If - sign was in
- ; command parameter, also delete
- ; empty lines completely.
-
- trunc1: mov count,0 ; initialize column counter
- xor bp,bp ; init line pointer
-
- trunc2: call cin ; read a character
- mov al,char ; is it carriage return
- and al,07fh ; (ignore high bit in case
- cmp al,cr ; this is Wordstar file)
- je trunc3 ; yes, go process end of line
- mov al,char ; transfer char. to forming line
- mov byte ptr ds:[line+bp],al
- inc bp
- cmp char,blank ; is character a space code?
- je trunc2 ; yes, get next char
- mov count,bp ; no, update column count
- jmp trunc2 ; get next char.
-
- trunc3: xor bp,bp ; text string now in LINE
- call cin ; discard line feed
- cmp count,0 ; was line empty?
- jne trunc4 ; no, go output it
- cmp sign,0 ; deleting empty lines?
- jne trunc1 ; yes, discard this one
- jmp trunc5 ; no, send cr-lf sequence
-
- trunc4: ; now transfer LINE to BUFOUT
- mov al,byte ptr ds:[bp+line]
- mov char,al ; get next char and
- call cout ; send it to output
- inc bp
- cmp bp,count ; entire line sent yet?
- jb trunc4 ; no, send another char
-
- trunc5: mov char,cr ; send carriage return
- call cout
- mov char,lf ; and line feed
- call cout
- jmp trunc1
-
- exit: cmp di,0 ; output buffer empty?
- je exit1 ; yes
- call outbuf ; no, flush it
- exit1: mov ax,4c00h ; exit with return code=0
- int 21h ; if no errors were encountered
-
-
- err: ; print error message and exit.
- ; DS:DX = addr of message
- ; CX = length of message
- ; AL = return code
- push ax ; save return code
- mov ah,40h ; function 40 = write
- mov bx,stderr ; handle for error output
- int 21h
- pop ax ; retrieve return code
- mov ah,4ch ; function 4C = exit
- int 21h
-
- err1: mov dx,offset err1msg ; print "output device error"
- mov cx,err1len
- mov al,1 ; return code = 1
- jmp err
-
- err2: mov dx,offset err2msg ; print "disk is full".
- mov cx,err2len
- mov al,2 ; return code = 2
- jmp err
-
- err3: mov dx,offset err3msg ; print "bad parameter"
- mov cx,err3len
- mov al,3 ; return code = 3
- jmp err
-
- err4: mov dx,offset err4msg ; print "input device error"
- mov cx,err4len
- mov al,4 ; return code = 4
- jmp err
-
-
- trim endp
-
-
- cout proc near ; output contents of "char"
- ; with autobuffering
- mov al,char
- mov byte ptr [di+bufout],al
- inc di
- cmp di,buflen ; buffer full yet?
- jb cout1
- call outbuf ; write buffer
- cout1: ret ; back to caller
- cout endp
-
-
- outbuf proc near ; write buffer to std output
- mov ah,40h ; function 40 = write
- mov bx,stdout ; predefined handle
- mov cx,di ; number of characters
- lea dx,bufout ; DS:DX = buffer addr
- int 21h ; request DOS service
- jc err1 ; jump, device write error
- cmp ax,di
- jne err2 ; jump, disk is full
- xor di,di ; initialize output buff pointer
- ret ; back to caller
- outbuf endp
-
-
- cin proc near ; input next char with buffering
- inc si ; bump input buffer pointer
- cmp si,topin ; buffer exhausted?
- jbe cin2 ; no, jump
- mov ah,3fh ; yes, read some more data
- mov bx,stdin ; predefined handle
- mov cx,buflen ; max length to read
- lea dx,bufin ; DS:DX = input buffer addr
- int 21h ; request DOS service
- jc err4 ; jump, input device error
- cmp ax,0 ; end of file?
- jne cin1
- jmp exit ; yes, goto success exit point
- cin1: dec ax ; save offset of top of data
- mov topin,ax
- xor si,si ; zero input buffer pointer
- cin2: mov al,byte ptr [si+bufin]
- mov char,al ; get next char
- ret
- cin endp
-
-
- getprm proc near ; convert numeric parameter to
- ; binary and return it in AX
- xor ax,ax ; initialize forming answer
- mov cl,[bx] ; get first char
- cmp cl,'-' ; is it minus sign?
- jne getp2 ; no, jump
- inc sign ; yes, set flag and
- getp1: inc bx ; bump command string pointer
- ; past the "-" sign
- mov cl,[bx] ; get next char
- getp2: cmp cl,'0' ; at least 1 legal digit?
- jb getp6 ; no, exit
- cmp cl,'9'
- ja getp6 ; no, exit
- jmp getp4
- getp3: inc bx ; advance through string
- mov cl,[bx]
- cmp cl,'0' ; make sure legal digit 0-9
- jb getp5 ; not digit, jump
- cmp cl,'9'
- ja getp5 ; not digit, jump
- mov dl,10 ; previous answer * 10
- mul dl
- getp4: sub cl,'0' ; add in the new digit
- xor ch,ch
- add ax,cx
- cmp ah,0 ; new answer > 255?
- je getp3 ; no, keep converting
- jmp err3 ; yes, illegal parameter, exit
- getp5: cmp byte ptr[bx],blank ; if not digit, must be blank
- jne getp6 ; exit, bad parameter
- ret ; back to caller
- getp6: jmp err3 ; ... since too far to reach
- ; direct with conditional branch
- getprm endp
-
-
- err1msg db cr,lf
- db 'trim: output device error'
- db cr,lf
- err1len equ (this byte)-(offset err1msg)
-
- err2msg db cr,lf
- db 'trim: disk is full.'
- db cr,lf
- err2len equ (this byte)-(offset err2msg)
-
- err3msg db cr,lf
- db 'trim: bad parameter'
- db cr,lf
- err3len equ (this byte)-(offset err3msg)
-
- err4msg db cr,lf
- db 'trim: input device error'
- db cr,lf
- err4len equ (this byte)-(offset err4msg)
-
-
- bufin equ this byte ; data is read here
- ; from the standard input
-
- bufout equ bufin+buflen ; data to be written to
- ; standard output is built here
-
- line equ bufout+buflen ; temporary line buffer
-
-
- cseg ends
-
- end start